/**
 * 简单版深拷贝，只考虑普通对象属性，不考虑内置对象和函数,使用deepclone进行克隆。
 * 高级版深拷贝, 使用通过Object.create和Object.defineProperty获取对象的所有属性，返回一个新的对象
 * 如果只是对对象进行深拷贝，可以直接将对象转换成字符串，然后再转换回来。
 */


//待拷贝对象
var pserson = {
  name: '休闲玩家Mick',
  url: 'www.liyublogs.top',
  age: 18,
  f: function () {
    this.age = 22
  },
  date: new Date(),
  rex: new RegExp(),
}


/**
 * 方法一
 */
function deepClone(obj) {
  //先对传入的实参进行判断，若不是对象类型，则直接返回.
  if (typeof obj !== 'object') {
    return;
  }
  var newObj = obj.constructor === Array ? [] : {};
  //遍历函数的键值
  for (let key in obj) {
    //判断对象里是否有该属性
    if (obj.hasOwnProperty(key)) {
      newObj[key] = typeof obj[key] === 'object' ? deepClone(obj[key]) : obj[key]
    }
  }
  return newObj
}

/**
 * 上面的方法无法拷贝Data对象.
 * Object.getPrototypeOf()
 */
console.log(deepClone(pserson))


/**
 * 方法二
 */
function deepClone2(obj) {
  /**
   * 使用Object.create创建对象
   * 
   */
  var newObj = Object.create(Object.getPrototypeOf(obj));
  copyOwnPropertiesFrom(newObj, obj);
  return newObj;
}

function copyOwnPropertiesFrom(target, source) {
  Object.getOwnPropertyNames(source).forEach(item => {
    //获取每个属性的所有描述,然后重新定义对象的属性返回此对象
    var desc = Object.getOwnPropertyDescriptor(source, item);
    Object.defineProperty(target, item, desc);
  })

  return target;
}

console.log(deepClone2(pserson))

/**
 * 方法三
 * @param {Object} obj 深拷贝对象
 * 只针对对象的深拷贝
 * 方法：将对象转成字符串，然后再转换成对象
 */
const deepCopy = obj => JSON.parse(JSON.stringify(obj))
console.log(deepCopy(pserson))



